/**
 * [description]同意处理url地址
 * @param  {[type]} url [description]
 * @return {[type]}     [description]
 */
/**
 * [description]同意处理url地址
 * @param  {[type]} url [description]
 * @return {[type]}     [description]
 */
export const dealurl = (url) => {
  if (url.indexOf('?') > -1) {
    let queryStr = url.split('com/')[1]
    return 'type=' + queryStr.split('?')[0] + '?' + queryStr.split('?')[1]
  } else if (url.indexOf('mp4') > -1) {
    // 视频
    return 'type=' + url
  } else {
    // 首页单个视频
    return 'video=' + url
  }
}
/**
 * [description]返回需要的地址
 * @param  {[type]} obj [description]
 * @return {[type]}     [description]
 */
export const getUrl = (obj) => {
  let type = obj.type;
  delete obj.type;
  let otherParams = '';
  for (let i in obj) {
    otherParams += "&" + i + "=" + obj[i]
  }
  return type + otherParams
}
/*
* 获取style样式
* */
export const getStyle = (element, attr, NumberMode = 'int') => {
  let target
  // scrollTop 获取方式不同，没有它不属于style，而且只有document.body才能用
  if (attr === 'scrollTop') {
    target = element.scrollTop
  } else if (element.currentStyle) {
    console.log(element.constructor)
    target = element.currentStyle[attr]
  } else {
    target = document.defaultView.getComputedStyle(element, null)[attr]
  }
  // 在获取opctiy 时需要获取小数parseFloat
  return NumberMode === 'float' ? parseFloat(target) : parseInt(target)
}
/*
* 运动效果
* @param {HTMLElement} element 运动对象，必选
* @param {JSON}        target  属性：  目标值，必选
* @param {number}      duration 运动时间，可选
* @param {string}       mode    运动模式，可选
* @param  {function}    callback  可选，回调函数，链式动画
* */
export const animate = (element, target, duration = 400, mode = 'ease-out', callback) => {
  // 清除运动对象的定时器
  clearInterval(element.timer)

  // 判断运动时间不同参数的情况
  if (duration instanceof Function) {
    callback = duration
    duration = 400
  } else if (duration instanceof String) {
    mode = duration
    duration = 400
  }

  // 判断运动模式不同参数的情况
  if (mode instanceof Function) {
    callback = mode
    mode = 'ease-out'
  }

  // 获取dom
  const attrStyle = attr => {
    if (attr === 'opactiy') {
      return Math.round(getStyle(element, attr, 'float') * 100)
    } else {
      return getStyle(element, attr)
    }
  }
  // 跟字体大小，需要从此将rem 改成px进行运算
  const rootSize = parseFloat(document.documentElement.style.fontSize)

  const unit = new Object()
  const initState = new Object()
  // 获取目标属性单位和初始样式值
  Object.keys(target).forEach(attr => {
    if (/[^\d^\.]+/gi.test(target[attr])) {
      unit[attr] = target[attr].match(/[^\d^\.]+/gi)[0] || 'px'
    } else {
      unit[attr] = 'px'
    }
    initState[attr] = attrStyle(attr)
  })
  // 去掉传入的后缀单位
  Object.keys(target).forEach(attr => {
    if (unit[attr] == 'rem') {
      target[attr] = Math.ceil(parseInt(target[attr] * rootSize))
    } else {
      target[attr] = parseInt(target[attr])
    }
  })

  let flag = true // 假设所有运动达到终点
  const remberSpeed = {} // 记录上一个速度值，在ease-in模式下需要用到
  element.timer = setInterval(() => {
    Object.keys(target).forEach(attr => {
      let iSpeed = 0 // 步长
      let status = false // 是否仍需运动
      let iCurrent = attrStyle(attr) || 0 // 当前元素属性值
      let speedBase = 0 //目标点需要减去的基础值，三种运动状态的值都不同
      let intervalTime // 将目标值分为多少步长执行，数值越大，步长越小，运动时间越长
      switch (mode) {
        case 'ease-out':
          speedBase = iCurrent
          intervalTime = duration * 5 / 400
          break
        case 'linear':
          speedBase = initState[attr]
          intervalTime = duration * 20 / 400
          break
        case 'ease-in':
          let oldspeed = remberSpeed[attr] || 0
          iSpeed = oldspeed + (target[attr] - initState[attr]) / duration
          remberSpeed[attr] = iSpeed
          break
        default:
          speedBase = iCurrent
          intervalTime = duration * 5 / 400
      }
      if (mode !== 'ease-in') {
        iSpeed = (target[attr] - speedBase) / intervalTime
        iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed)
      }
      // 判断是否达到步长之内的误差距离，如果到达目标点
      switch (mode) {
        case 'ease-out':
          status = iCurrent != target[attr]
          break
        case 'linear':
          status = Math.abs(Math.abs(iCurrent) - Math.abs(target[attr])) > Math.abs(iSpeed)
          break
        case 'ease-in':
          status = Math.abs(Math.abs(iCurrent) - Math.abs(target[attr])) > Math.abs(iSpeed)
          break
        default:
          status = iCurrent != target[attr]
      }

      if (status) {
        flag = false
        // opactiy 和 scrollTop 需要特殊处理
        if (attr === 'opacity') {
          element.style.filter = 'alpha(opacity:' + (iCurrent + iSpeed) + ')'
          element.style.opacity = (iCurrent + iSpeed) / 100
        } else if (attr === 'scrollTop') {
          element.scrollTop = iCurrent + iSpeed
        } else {
          element.style[attr] = iCurrent + iSpeed + 'px'
        }
      } else {
        flag = true
      }
      if (flag) {
        clearInterval(element.timer)
        if (callback) {
          callback()
        }
      }
    })
  }, 20)
}
/*
* 获取元素偏移的高度
* */
export const getOuterHeight = (element) => {
  let innerHeight = element.offsetHeight
  let marginHeight = getStyle(element, 'marginTop') + getStyle(element, 'marginBottom')
  return innerHeight + marginHeight
}
/*
* 显示返回顶部按钮，开始、结束、运动 三个过程中调用函数判断是否达到目标点
* */
export const showBack = callback => {
  let requestFram
  let oldScrollTop

  document.addEventListener('scroll', () => {
    showBackFun()
  }, false)
  document.addEventListener('touchstart', () => {
    showBackFun()
  },{passive: true})
  document.addEventListener('touchmove', () => {
    showBackFun()
  },{passive:true})
  document.addEventListener('touchend', () => {
    oldScrollTop = document.body.scrollTop
    moveEnd();
  },{passive:true})

  const moveEnd = () => {
    requestFram = requestAnimationFrame(() => {
      if(document.body.scrollTop != oldScrollTop){
        oldScrollTop = document.body.scrollTop
        moveEnd()
      }else{
        cancelAnimationFrame(requestFram)
      }
      showBackFun()
    })
  }

  // 判断是否达到目标点
  const showBackFun = () => {
    if (document.body.scrollTop > 400) {
      callback(true)
    } else {
      callback(false)
    }
  }
}
